public class OddEven {
	public static void main(String[] args) {
		OddEvenPrinter oep = new OddEvenPrinter();
		MyThread1 t1 = new MyThread1(oep);
		MyThread2 t2 = new MyThread2(oep);
		t1.start();
		t2.start();
		System.out.println("End of Mian...");
	}
}

class OddEvenPrinter {

	boolean evenTurn = true;

	public synchronized void printOdd(int num) {
		while (evenTurn) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
		System.out.println(Thread.currentThread().getName() + " " + num);
		evenTurn = true;
		notifyAll();
	}

	public synchronized void printEven(int num) {
		while (!evenTurn) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
		System.out.println(Thread.currentThread().getName() + " " + num);
		evenTurn = false;
		notifyAll();
	}
}

class MyThread1 extends Thread {

	private OddEvenPrinter printerObj = null;
	int count = 0;

	MyThread1(OddEvenPrinter oep) {
		this.printerObj = oep;
	}

	public void run() {
		while (count < 20) {
			printerObj.printEven(count);
			count = count + 2;
		}
	}
}

class MyThread2 extends Thread {

	private OddEvenPrinter printerObj = null;
	int count = 1;

	MyThread2(OddEvenPrinter oep) {
		this.printerObj = oep;
	}

	public void run() {
		while (count < 20) {
			printerObj.printOdd(count);
			count = count + 2;
		}
	}
}